/*
 * This file has been strongly influenced by PhotoView.java, InterestView.java
 * 
 * @Ying: This is where you set up the GUI, you'll figure it out
 * */

//TODO: Logging Stuff, could be added to make debugging easier

package com.googlecode.eightqueenshaggle;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.text.Editable;

import android.net.Uri;
import android.database.Cursor;

//[VW] I'll do the haggle stuff at last, because then I can easily run/debug the code in the VM
//Haggle Imports
/*import org.haggle.Attribute;
 import org.haggle.DataObject;
 import org.haggle.Handle;
 import org.haggle.Node;
 import org.haggle.LaunchCallback;*/

//import from our own project
import com.googlecode.eightqueenshaggle.EQDatabaseContentProvider;

import com.googlecode.eightqueenshaggle.Puzzle;
import com.googlecode.eightqueenshaggle.Solution;

public class CmdController extends Activity {

	public static final int MENU_NEW_GAME  = 1;
	public static final int MENU_NEW_GAME_CMD = 2;
	public static final int MENU_VIEW_SOLUTIONS = 3;
	public static final int MENU_QUIT = 4;
	
	// this object can be used to access the text the user has typed
	private EditText entry;

	// this object will be used to print output to
	private TextView tv;

	// represent a game
	Puzzle classicalPuzzle;
	Solution presConfig;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		
		// this makes it use the layout from the /res/main.xml
		setContentView(R.layout.cmd);

		entry = (EditText) findViewById(R.id.entry);
		tv = (TextView) findViewById(R.id.pseudoTerminal);

		// parse the input if the user presses enter
		entry.setOnKeyListener(new View.OnKeyListener() {
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				switch (keyCode) {
				case KeyEvent.KEYCODE_ENTER:
					if (entry.hasFocus()) {
						parseEntry();
					}
					return true;
				}
				return false;
			}
		});

		// parse the input if the user presses the exec button
		final Button execButton = (Button) findViewById(R.id.exec_button);
		execButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				// Perform action on click
				parseEntry();
			}
		});

		
		
		// set up a little game
		classicalPuzzle = new Puzzle(8, 8, 8, 91, "classicalPuzzle");
		presConfig = new Solution(classicalPuzzle);

		tv.setText("classsical 8 queens problem, press h for help");

	}

	/*
	 * @Override public void onCreateContextMenu(ContextMenu menu, View v,
	 * ContextMenuInfo menuInfo) {
	 * menu.setHeaderTitle("8 Queens Haggle Terminal"); menu.add("Delete");
	 * menu.add("Cancel"); }
	 */

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
				.getMenuInfo();

		return true;
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
	}

	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
	}

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		switch (keyCode) {
		case KeyEvent.KEYCODE_BACK:

			break;
		}

		return super.onKeyDown(keyCode, event);
	}

	public void parseEntry() {

		Editable ed = entry.getText();
		String command = ed.toString();

		if (command == null || command.length() == 0)
			return;

		String[] split = command.split(" ");

		command = split[0];
		command = command.trim();

		/*
		 * for (int i = 0; i < split.length; i++) { String[] split2 =
		 * split[i].split(":");
		 */
		// long weight;

		/*
		 * if (split2.length == 2) { try { // weight =
		 * Long.parseLong(split2[1]); } catch (Exception ex) { // Just ignore
		 * and use default weight } command = split2[0]; }
		 * 
		 * // Remove any trailing whitespaces and other non-wanted characters
		 * command = command.trim();
		 * 
		 * }
		 */

		if (command.equals("h")) { // print the current queen placement

			tv
					.setText("solve the classical 8 queens problem,\n p: print the current field\n a <x> <y>: add a queen in location (x,y)\n r <x> <y>: remove a queen from location (x,y)\n enumartion of x,y starts at 0\n have fun!");

		}
		
		if (command.equals("m")) { // print the current queen placement

			setContentView(R.layout.main_menu);
		}
		
		if (command.equals("q")) { // print the current queen placement

			Intent intent = new Intent(this, BoardViewController.class); 
            startActivity(intent); 
            finish();
			//setContentView(R.layout.board);
		}

		if (command.equals("p")) { // print the current queen placement

			cmdLinePrintField();

		}

		if (command.equals("a") && split.length == 3) { // add a queen on the
														// field

			if ( // TODO: There is no error checking here, is the input really
					// an integer
			cmdLineAddQueen(Integer.parseInt(split[1]), Integer
					.parseInt(split[2]))) {

				cmdLinePrintField();
				
				//check if the game is solved
				if(classicalPuzzle.amountQueens == presConfig.getCurQueenCount()){
					
					tv.setText("congratulations!\nyou found a solution!\n");
				}

			} else {

				tv.setText("Illegal placement");
			}
		}

		if (command.equals("r") && split.length == 3) {

			if ( // TODO: There is no error checking here, is the input really
					// an integer
			cmdLineRemoveQueen(Integer.parseInt(split[1]), Integer
					.parseInt(split[2]))) {

				cmdLinePrintField();

			} else {

				tv.setText("Queen could not be removed, does not exist");
			}

		}
		
		if(command.equals("dbv")){ //view the database
			
			cmdLineViewSolutions();
			
		}
		
		if(command.equals("dba")){ //add a record to the database
			
			cmdLineAddSolution2DB();
			
		}

		ed.clear();

	}

	public void cmdLinePrintField() {

		String fieldView = "";

		for (int i = 0; i < this.classicalPuzzle.dim1; i++) {
			for (int j = 0; j < this.classicalPuzzle.dim2; j++) {

				fieldView += "0"; // add a zero in every case
				
				//TODO: use function checkQueen(...) instead of this
				for (int k = 0; k < presConfig.queensLocations.size(); k++) {

					if (presConfig.queensLocations.elementAt(k).x == i
							&& presConfig.queensLocations.elementAt(k).y == j) {

						// if a queen is present, remove "0" and write x instead
						fieldView = fieldView.subSequence(0,
								fieldView.length() - 1)
								+ "x";

					}

				}

			}

			fieldView += "\n";
		}

		tv.setText(fieldView);

	}

	public boolean cmdLineAddQueen(int x, int y) {

		return presConfig.addQueen(x, y);

	}

	public boolean cmdLineRemoveQueen(int x, int y) {

		return presConfig.removeQueen(x, y);

	}
	
	public boolean cmdLineViewSolutions(){
		
		// this object is needed to connect to the db
		ContentResolver cr;
		
		// connect to the database and check if we already have some solutions
		cr = getContentResolver();
		
		// Make the query.
		// [VW] The DB part does not work yet, I'll have to recheck it
		
		
		Cursor managedCursor =
			managedQuery(
						EQDatabaseContentProvider.CONTENT_URI, 
						null, // Which columns to return
						null, // Which rows to return (all rows) 
						null, //Selection arguments (none) 
						EQDatabaseContentProvider.DEFAULT_SORT_ORDER
						);
		 
		//[VW] This shit does not work, so at least we get no crash
		if(managedCursor == null)
			return false;
		
		 int colCount = managedCursor.getColumnCount();
		 
		 if(colCount != 0){
			 return true;
		 }
			 
		return false;
		
		 //TODO
	}

	public boolean cmdLineAddSolution2DB(){ //tODO: This can actually not be used, because the values are hardcoded
		
		ContentValues values = new ContentValues();
		
		//this is no solution i just want to work with the db
		values.put("loc1x", 0);
		values.put("loc1y", 1);
		values.put("loc2x", 2);
		values.put("loc2y", 3);
		values.put("loc3x", 4);
		values.put("loc3y", 5);
		values.put("loc4x", 6);
		values.put("loc4y", 7);
		values.put("loc5x", 0);
		values.put("loc5y", 1);
		values.put("loc6x", 2);
		values.put("loc6y", 3);
		values.put("loc7x", 4);
		values.put("loc7y", 5);
		values.put("loc8x", 6);
		values.put("loc8y", 7);
		
		//this statement fails, tell me why?
		Uri uri = getContentResolver().insert(EQDatabaseContentProvider.CONTENT_URI, values);
		
        if (uri == null) {
        	return false;
        }
		
		return true;
		
	}
	
	/* Creates the menu items */
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);

        menu.add(0, MENU_NEW_GAME, 0, "New Game");
        menu.add(0, MENU_NEW_GAME_CMD, 0, "New Game (cmd)");
        menu.add(0, MENU_VIEW_SOLUTIONS, 0, "View Solutions");
        menu.add(0, MENU_QUIT, 0, "Quit");
	    return true;
	}
	
	/* Handles item selections */
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch (item.getItemId()) {
	    case MENU_NEW_GAME:
	        newGame();
	        return true;
	    case MENU_NEW_GAME_CMD:
	        newGameCmd();
	        return true;
	    case MENU_VIEW_SOLUTIONS:
	        viewSolutions();
	        return true;
	    case MENU_QUIT:
	    	this.finish();
	        return true;
	    }
	    return false;
	}

	private void viewSolutions() {
		// TODO view Solutions from DB
		
	}

	private void newGameCmd() {
		Intent intent = new Intent(this, CmdController.class); 
        startActivity(intent); 
        finish();
	}

	private void newGame() {
		Intent intent = new Intent(this, BoardViewController.class); 
        startActivity(intent); 
        finish();
	}
	
}